package cn.dida.controller;

import java.util.Date;
import java.util.HashMap;

import javax.servlet.http.HttpServletRequest;

import org.apache.commons.lang3.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.servlet.DispatcherServlet;
import org.springframework.web.servlet.ModelAndView;

import cn.dida.exception.BizzException;
import cn.dida.model.HttpResponseBodyWrapper;
import cn.dida.util.ExceptionUtil;

/**
 * <p>
 * 异常处理器，根据请求的类型（text\html、application\json），跳转至错误页或者返回json报文
 * </p>
 * 
 * @author weiwei
 */
@Controller
public class ErrorController extends BaseController {

	private Log loger = LogFactory.getLog(ErrorController.class);

	/**
	 * 页面请求异常，携带异常对象返回erro页面
	 * 
	 * @param request
	 * @return Object
	 */
	@RequestMapping(value = "/error", produces = { "text/html" })
	public Object error4Html(HttpServletRequest request) {
		HashMap<String, Object> data = getModel(request);

		String errorpage = "error";
		Throwable ex = (Exception) request.getAttribute(DispatcherServlet.EXCEPTION_ATTRIBUTE);
		
		if (ex == null) {
			ex = (Throwable) request.getAttribute("javax.servlet.error.exception");
		}
		
		if (ex instanceof BizzException) {
			BizzException bizzException = (BizzException) ex;
			if (bizzException.getCode() == BizzException.error_code_unauthorized) {
				errorpage = "unauthorized";
			}
		}

		ExceptionUtil.logerErrorMes(loger, ex);

		return new ModelAndView(errorpage).addAllObjects(data);
	}

	/**
	 * ajax请求异常，返回json
	 * 
	 * @param request
	 * @return Object
	 */
	@ResponseBody
	@RequestMapping("/error")
	public Object error4Ajax(HttpServletRequest request) {
		Throwable ex = (Exception) request.getAttribute(DispatcherServlet.EXCEPTION_ATTRIBUTE);
		if (ex == null) {
			ex = (Throwable) request.getAttribute("javax.servlet.error.exception");
		}

		if (ex instanceof BizzException) {
			return wrapBizzExcetionToResponseBody((BizzException) ex);
		} else {

			ExceptionUtil.logerErrorMes(loger, ex);

			BizzException unknownExcetion = new BizzException(BizzException.error_code_unknown);
			HttpResponseBodyWrapper responseBodyWrapper = wrapBizzExcetionToResponseBody(unknownExcetion);
			return responseBodyWrapper;
		}
	}

	private HashMap<String, Object> getModel(HttpServletRequest request) {
		HashMap<String, Object> data = new HashMap<>();
		Throwable ex = (Exception) request.getAttribute(DispatcherServlet.EXCEPTION_ATTRIBUTE);
		if (ex == null) {
			ex = (Throwable) request.getAttribute("javax.servlet.error.exception");
		}
		Integer status = (Integer) request.getAttribute("javax.servlet.error.status_code");
		if (null == status) {
			status = 500;
		}
		data.put("status", status);
		data.put("timestamp", new Date());
		data.put("error", HttpStatus.valueOf(status).getReasonPhrase());
		Object trackMsg = request.getAttribute("javax.servlet.error.message");
		String message = trackMsg == null ? null : trackMsg.toString();
		if (StringUtils.isEmpty(message) && ex != null) {
			message = ex.getMessage();
			logger.error(message);
			//ex.printStackTrace();
		}
		data.put("message", message);
		return data;
	}

	private HttpResponseBodyWrapper wrapBizzExcetionToResponseBody(BizzException exception) {
		return new HttpResponseBodyWrapper(exception.getCode(), exception.getData(), exception.getMessage());
	}

}
